#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <memory>

static const string prosep ="\r\n";
std::string Encode(const std::string& jsonstr)
{
	std::string lenstr = to_string(jsonstr.size());
	return lenstr +prosep+ jsonstr+prosep;
};
std::string Decode(std::string& packagestream)
{
	size_t pos =packagestream.find(prosep);
	if(pos==string::npos)
		return std::string();
	std::string lenstr = packagestream.substr(0,pos);
	int len = std::stoi(lenstr);
	int realsize = len+lenstr.size()+2*prosep.size();
	if(packagestream.size()<realsize)
		return std::string();
	std::string jsonstr = packagestream.substr(pos+prosep.size(),len);
	packagestream.erase(0,realsize);
	return jsonstr;

};
class Request
{
public:
	Request()
	{};
	Request(int x,int y,char oper):_x(x),_y(y),_oper(oper)
	{};
	void Serialize(std::string *out)
	{
		Json::Value root;
		root["x"]=_x;
		root["y"]=_y;
		root["oper"]=_oper;
		Json::FastWriter writer;
		*out = writer.write(root);
	};
	bool Deserialize(const std::string& in)
	{
		Json::Reader reader;
		Json::Value root;
		bool res = reader.parse(in,root);
	//	if(!res) return false;
		_x = root["x"].asInt();
		_y = root["y"].asInt();
		_oper = root["oper"].asInt();
		return true;
	};
	int X()
	{return _x;};
	int Y()
	{return _y;};
	char Oper()
	{return _oper;};
	void Print()
	{
		cout<<_x<<(char)_oper<<_y<<"=?"<<endl;
	};
private:
	int _x;
	int _y;
	char _oper;
};
class Response
{
public:
        Response():_result(0),_code(0),_desc("sucess")
        {};
        void Serialize(std::string *out)
        {
                Json::Value root;
                root["result"]=_result;
                root["code"]=_code;
                root["desc"]=_desc;
                Json::FastWriter writer;
                *out = writer.write(root);
        };
        bool Deserialize(const std::string& in)
        {
                Json::Reader reader;
                Json::Value root;
                bool res = reader.parse(in,root);
		if(!res) return false;
                _result = root["result"].asInt();
                _code = root["code"].asInt();
                _desc = root["desc"].asString();
		return true;
        };
	int Result()
	{return _result;};
	int Code()
	{return _code;};
	string Desc()
	{return _desc;};
	void Print()
	{
		cout<<"result:"<<_result<<endl;
		cout<<"code:"<<_code<<endl;
		cout<<"desc:"<<_desc<<endl;
	};

public:
	int _result;
	int _code;// 0:success 1.div zero 2.mod zero 3.illegal operation
	string _desc;
};


